package com.wolfsea.launcherdemo
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.core.view.get

/**
 *@desc  SlideContentLayout
 *@author liuliheng
 *@time 2022/12/20  10:24
 **/
class SlideContentLayout @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null
) : ViewGroup(context, attributeSet), View.OnClickListener {

    private var viewTotalHeight = 0
    private var canMovedHeight = 0

    private var downX = 0
    private var downY = 0
    private var flagDownX = 0
    private var flagDownY = 0

    private var totalMovedY = 0

    private var moveEnabled = false
    private var notInMoving = true

    init {
        inflate(context, R.layout.slide_content_layout, this)

        findViewById<View>(R.id.view1).setOnClickListener(this)
        findViewById<View>(R.id.view2).setOnClickListener(this)
        findViewById<View>(R.id.view3).setOnClickListener(this)
        findViewById<View>(R.id.view4).setOnClickListener(this)
        findViewById<View>(R.id.view5).setOnClickListener(this)
        findViewById<View>(R.id.view6).setOnClickListener(this)
        findViewById<View>(R.id.view7).setOnClickListener(this)
        findViewById<View>(R.id.view8).setOnClickListener(this)
        findViewById<View>(R.id.view9).setOnClickListener(this)
        findViewById<View>(R.id.view10).setOnClickListener(this)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        Log.d(TAG, "onMeasure--childCount:${childCount}")
        var measureHeight = 0
        val view = get(0)
        val viewLayoutParams = view.layoutParams as MarginLayoutParams
        measureHeight += viewLayoutParams.topMargin
        if (view is ViewGroup) {
            val childCount = view.childCount
            Log.d(TAG, "onMeasure--new--new--childCount:${childCount}")
            for (j in 0.until(childCount)) {
                val child = view[j]
                measureChildWithMargins(view[j], widthMeasureSpec, 0, heightMeasureSpec, 0)
                val childLayoutParams = child.layoutParams as LinearLayoutCompat.LayoutParams
                measureHeight += child.measuredHeight + childLayoutParams.topMargin
                if (j == childCount - 1) {
                    measureHeight += childLayoutParams.bottomMargin
                }
            }
        }

        //父view的高为边距高和所有子view高之和
        measureChildWithMargins(
            view,
            widthMeasureSpec,
            0,
            MeasureSpec.makeMeasureSpec(measureHeight, MeasureSpec.EXACTLY),
            0
        )

        setMeasuredDimension(
            MeasureSpec.getSize(widthMeasureSpec) - paddingStart - paddingEnd,
            MeasureSpec.getSize(heightMeasureSpec) - paddingTop - paddingBottom
        )
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        canMovedHeight = 0
        viewTotalHeight = 0

        val view = get(0)
        val viewLayoutParams = view.layoutParams as MarginLayoutParams
        view.layout(
            viewLayoutParams.leftMargin,
            viewLayoutParams.topMargin,
            viewLayoutParams.leftMargin + view.measuredWidth,
            viewLayoutParams.topMargin + view.measuredHeight
        )
        viewTotalHeight += viewLayoutParams.topMargin

        if (view is ViewGroup) {
            val childCount = view.childCount
            var preChildHeight = 0
            for (j in 0.until(childCount)) {
                val child = view[j]
                val childWidth = child.measuredWidth
                val childHeight = child.measuredHeight
                val childLayoutParams = child.layoutParams as LinearLayoutCompat.LayoutParams
                child.layout(
                    childLayoutParams.leftMargin,
                    preChildHeight + childLayoutParams.topMargin,
                    childLayoutParams.leftMargin + childWidth,
                    preChildHeight + childLayoutParams.topMargin + childHeight
                )
                viewTotalHeight += childHeight + childLayoutParams.topMargin + childLayoutParams.bottomMargin
                preChildHeight += childHeight + childLayoutParams.topMargin
            }
        }

        canMovedHeight = viewTotalHeight - height
        moveEnabled = canMovedHeight > 0
    }

    override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
        return MarginLayoutParams(context, attrs)
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> {
                flagDownX = ev.x.toInt()
                downX = flagDownX
                flagDownY = ev.y.toInt()
                downY = flagDownY
            }
            MotionEvent.ACTION_MOVE -> {
                val moveX = ev.x.toInt()
                val moveY = ev.y.toInt()
                val diffValueX = moveX - downX
                val diffValueY = moveY - downY
                val condition = Math.abs(diffValueY) > Math.abs(diffValueX)
                if (condition && moveEnabled) {
                    downX = moveX
                    downY = moveY
                    return true
                }
            }
        }
        return super.onInterceptTouchEvent(ev)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        performClick()
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                flagDownX = event.x.toInt()
                downX = flagDownX
                flagDownY = event.y.toInt()
                downY = flagDownY
            }
            MotionEvent.ACTION_MOVE -> {
                val moveY = event.y.toInt()
                val diffValueY = moveY - downY
                totalMovedY += diffValueY
                totalMovedY = if (diffValueY > 0) {
                    //下滑
                    Math.min(0, totalMovedY)
                } else {
                    //上滑
                    Math.max(totalMovedY, -canMovedHeight)
                }
                scrollTo(0, -totalMovedY)
                downY = moveY
                notInMoving = false
            }
            MotionEvent.ACTION_UP -> {
                notInMoving = true
            }
        }
        return true
    }

    override fun performClick(): Boolean {
        return super.performClick()
    }

    override fun onClick(view: View?) {
        view?.apply {
            when (id) {
                R.id.view1 -> {
                    context.showToast("view1")
                }
                R.id.view2 -> {
                    context.showToast("view2")
                }
                R.id.view3 -> {
                    context.showToast("view3")
                }
                R.id.view4 -> {
                    context.showToast("view4")
                }
                R.id.view5 -> {
                    context.showToast("view5")
                }
                R.id.view6 -> {
                    context.showToast("view6")
                }
                R.id.view7 -> {
                    context.showToast("view7")
                }
                R.id.view8 -> {
                    context.showToast("view8")
                }
                R.id.view9 -> {
                    context.showToast("view9")
                }
                R.id.view10 -> {
                    context.showToast("view10")
                }
            }
        }
    }

    fun inOriginState(): Boolean = totalMovedY == 0 && notInMoving

    companion object {
        const val TAG = "SlideContentLayout"
    }
}